package tool

import (
	"crypto"
	"crypto/md5"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/base64"
	"encoding/hex"
	"encoding/pem"
	"fmt"
	"sort"
	"strings"
)

func Sign(data map[string]interface{}, secret, subPrivateKey string) (string, error) {
	// 1. 将接口中的请求字段按照 ASCII 码方式进行升序排序
	var sortKeys []string
	for key := range data {
		sortKeys = append(sortKeys, key)
	}
	sort.Strings(sortKeys) // 对 key 进行排序

	// 2. 按照 key1=val1&key2=val2&key3=val3....&key=md5秘钥生成加密字符串
	var sb strings.Builder
	for _, k := range sortKeys {
		sb.WriteString(fmt.Sprintf("%s=%v&", k, data[k]))
	}
	sb.WriteString(fmt.Sprintf("key=%s", secret))
	str := sb.String()

	// 3: MD5 hash the string and convert to uppercase
	hash := md5.Sum([]byte(str))

	md5Str := hex.EncodeToString(hash[:])

	md5Str = strings.ToUpper(md5Str)
	fmt.Println("md5---\n", md5Str)

	tempPrivateKey := "-----BEGIN RSA PRIVATE KEY-----\n" + subPrivateKey + "\n-----END RSA PRIVATE KEY-----\n"
	// 解码PEM格式的RSA私钥
	block, _ := pem.Decode([]byte(tempPrivateKey))
	if block == nil {
		return "", fmt.Errorf("failed to decode private key")
	}

	// 解析PKCS#8编码的RSA私钥
	privateKey, err := parsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		return "", fmt.Errorf("failed to parse rsa private key:", err)
	}

	// 计算数据的SHA-256哈希值
	hashed := sha256.Sum256([]byte(md5Str))

	// 对哈希值进行RSA签名
	signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), crypto.SHA256, hashed[:])
	if err != nil {
		return "", fmt.Errorf("Error signing:", err)
	}
	// 将签名结果转为Base64字符串
	signatureBase64 := base64.StdEncoding.EncodeToString(signature)
	return signatureBase64, nil
}

func parsePKCS8PrivateKey(keyBytes []byte) (interface{}, error) {
	key, err := x509.ParsePKCS8PrivateKey(keyBytes)
	if err != nil {
		return nil, fmt.Errorf("failed to parse PKCS#8 private key: %v", err)
	}
	rsaKey, ok := key.(*rsa.PrivateKey)
	if !ok {
		return nil, fmt.Errorf("key is not an RSA private key")
	}
	return rsaKey, nil
}
